package view;

import javafx.application.Application;
import javafx.beans.property.*;
import javafx.beans.value.*;
import javafx.collections.*;
import javafx.event.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.FileChooser;
import javafx.stage.FileChooserBuilder;
import javafx.stage.Stage;

import java.io.File;
import java.util.Stack;

import javax.swing.JPanel;

import model.Paper;

/** 
 * This class displays a survey using a wizard 
 * @author Cody Thompson
 */
public class UploadPapers extends Application {
	
	private MainPanel mainP;
	
	public UploadPapers(MainPanel mp) {
		mainP = mp;
	}
	@Override
	public void start(Stage stage) {
		stage.setScene(new Scene(new UploadWizard(stage, mainP), 400, 250));
		stage.show();
	}
	/*public static void fun(String[] args) throws Exception { launch(args); }
	@Override public void start(Stage stage) throws Exception {
		// configure and display the scene and stage.
		stage.setScene(new Scene(new UploadWizard(stage), 400, 250));
		stage.show();
	}*/
	
}

/** basic wizard infrastructure class */
class Wizard extends StackPane {
	private static final int UNDEFINED = -1;
	private ObservableList<WizardPage> pages = FXCollections.observableArrayList();
	private Stack<Integer> history = new Stack<>();
	private int curPageIdx = UNDEFINED;

	Wizard(WizardPage... nodes) {
		pages.addAll(nodes);
		navTo(0);
		setStyle("-fx-padding: 10; -fx-background-color: cornsilk;");
	}

	void nextPage() {
		if (hasNextPage()) {
			navTo(curPageIdx + 1);
		}
	}

	void priorPage() {
		if (hasPriorPage()) {
			navTo(history.pop(), false);
		}
	}

	boolean hasNextPage() {
		return (curPageIdx < pages.size() - 1);
	}

	boolean hasPriorPage() {
		return !history.isEmpty();
	}

	void navTo(int nextPageIdx, boolean pushHistory) {
		if (nextPageIdx < 0 || nextPageIdx >= pages.size()) return;
		if (curPageIdx != UNDEFINED) {
			if (pushHistory) {
				history.push(curPageIdx);
			}
		}

		WizardPage nextPage = pages.get(nextPageIdx);
		curPageIdx = nextPageIdx;
		getChildren().clear();
		getChildren().add(nextPage);
		nextPage.manageButtons();
	}

	void navTo(int nextPageIdx) {
		navTo(nextPageIdx, true);
	}

	void navTo(String id) {
		Node page = lookup("#" + id);
		if (page != null) {
			int nextPageIdx = pages.indexOf(page);
			if (nextPageIdx != UNDEFINED) {
				navTo(nextPageIdx);
			}
		}
	}

	public void finish() {}
	public void cancel() {}
}

/** basic wizard page class */
abstract class WizardPage extends VBox {
	Button priorButton = new Button("_Previous");
	Button nextButton = new Button("N_ext");
	Button cancelButton = new Button("Cancel");
	Button finishButton = new Button("_Finish");

	WizardPage(String title) {
		getChildren().add(LabelBuilder.create().text(title).style("-fx-font-weight: bold; -fx-padding: 0 0 5 0;").build());
		setId(title);
		setSpacing(5);
		setStyle("-fx-padding:10; -fx-background-color: honeydew; -fx-border-color: derive(honeydew, -30%); -fx-border-width: 3;");

		Region spring = new Region();
		VBox.setVgrow(spring, Priority.ALWAYS);
		getChildren().addAll(getContent(), spring, getButtons());

		priorButton.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent actionEvent) {
				priorPage();
			}
		});
		nextButton.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent actionEvent) {
				nextPage();
			}
		});
		cancelButton.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent actionEvent) {
				getWizard().cancel();
			}
		});
		finishButton.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent actionEvent) {
				getWizard().finish();
			}
		});
	}

	HBox getButtons() {
		Region spring = new Region();
		HBox.setHgrow(spring, Priority.ALWAYS);
		HBox buttonBar = new HBox(5);
		cancelButton.setCancelButton(true);
		finishButton.setDefaultButton(true);
		buttonBar.getChildren().addAll(spring, priorButton, nextButton, cancelButton, finishButton);
		return buttonBar;
	}

	abstract Parent getContent();

	boolean hasNextPage() {
		return getWizard().hasNextPage();
	}

	boolean hasPriorPage() {
		return getWizard().hasPriorPage();
	}

	void nextPage() {
		getWizard().nextPage();
	}

	void priorPage() {
		getWizard().priorPage();
	}

	void navTo(String id) {
		getWizard().navTo(id);
	}

	Wizard getWizard() {
		return (Wizard) getParent();
	}

	public void manageButtons() {
		if (!hasPriorPage()) {
			priorButton.setDisable(true);
		}

		if (!hasNextPage()) {
			nextButton.setDisable(true);
		}
	}
}

/** This class shows a satisfaction survey */
class UploadWizard extends Wizard {
	private MainPanel mainP;
	Stage owner;
	public UploadWizard(Stage owner, MainPanel mp) {
		super(new CatagoryPage(), new TitlePage(), new KeywordsPage(), new AbstractPage(), new ChooseFilePage(), new ThanksPage());
		this.owner = owner;
		mainP = mp;
	}
	@Override
	public void finish() {
		Paper pap = new Paper(UploadData.instance.paper.getAbsoluteFile(), UploadData.instance.title.get(), 
				"e", UploadData.instance.key1.get(), UploadData.instance.abstrac.get());
		mainP.addPap(pap);
		owner.close();
	}
	@Override
	public void cancel() {
		System.out.println("Cancelled");
		owner.close();
	}
}

/** Simple placeholder class for the customer entered survey response. */
class UploadData {
	BooleanProperty category1 = new SimpleBooleanProperty();
	BooleanProperty category2 = new SimpleBooleanProperty();
	BooleanProperty category3 = new SimpleBooleanProperty();
	BooleanProperty category4 = new SimpleBooleanProperty();
	StringProperty title = new SimpleStringProperty();
	StringProperty abstrac = new SimpleStringProperty();
	StringProperty key1 = new SimpleStringProperty();
	StringProperty key2 = new SimpleStringProperty();
	StringProperty key3 = new SimpleStringProperty();
	StringProperty key4 = new SimpleStringProperty();
	StringProperty key5 = new SimpleStringProperty();
	File paper;
	
	void UploadPaper(File fle) {
		paper = fle;
	}
	static UploadData instance = new UploadData();
}

/**
 * This class determines what category the paper fits into.
 */
class CatagoryPage extends WizardPage {
	private RadioButton cat1;
	private RadioButton cat2;
	private RadioButton cat3;
	private RadioButton cat4;
	private ToggleGroup options = new ToggleGroup();

	public CatagoryPage() {
		super("Catagories");

		nextButton.setDisable(true);
		finishButton.setDisable(true);
		cat1.setToggleGroup(options);
		cat2.setToggleGroup(options);
		cat3.setToggleGroup(options);
		cat4.setToggleGroup(options);
		options.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
			@Override public void changed(ObservableValue<? extends Toggle> observableValue, Toggle oldToggle, Toggle newToggle) {
				nextButton.setDisable(false);
				
			}
		});
	}

	@Override
	Parent getContent() {
		cat1 = new RadioButton("Category 1");
		cat2 = new RadioButton("Category 2");
		cat3 = new RadioButton("Category 3");
		cat4 = new RadioButton("Category 4");
		UploadData.instance.category1.bind(cat1.selectedProperty());
		UploadData.instance.category2.bind(cat2.selectedProperty());
		UploadData.instance.category3.bind(cat3.selectedProperty());
		UploadData.instance.category4.bind(cat4.selectedProperty());
		return VBoxBuilder.create().spacing(5).children(
				new Label("Please pick the category that best fits your paper."), cat1, cat2, cat3, cat4
				).build();
	}

	@Override
	void nextPage() {
		super.nextPage();
	}
}

/** This page gathers the title of the paper */
class TitlePage extends WizardPage {
	public TitlePage() {
		super("Title");
	}

	@Override
	Parent getContent() {
		TextArea textArea = TextAreaBuilder.create().wrapText(true).promptText("Tell me what your paper is called").build();
		nextButton.setDisable(true);
		finishButton.setDisable(true);
		textArea.textProperty().addListener(new ChangeListener<String>() {
			@Override public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) {
				nextButton.setDisable(newValue.isEmpty());
			}
		});
		UploadData.instance.title.bind(textArea.textProperty());
		return VBoxBuilder.create().spacing(5).children(
				new Label("Please enter the title of your paper. (Max 100 chars.)"),
				textArea
				).build();
	}
}

class KeywordsPage extends WizardPage {
	public KeywordsPage() {
		super("Keywords");
	}
	@Override
	Parent getContent() {
		TextField txtField1 = TextFieldBuilder.create().build();
		TextField txtField2 = TextFieldBuilder.create().build();
		TextField txtField3 = TextFieldBuilder.create().build();
		TextField txtField4 = TextFieldBuilder.create().build();
		TextField txtField5 = TextFieldBuilder.create().build();
		nextButton.setDisable(true);
		finishButton.setDisable(true);
		txtField1.textProperty().addListener(new ChangeListener<String>() {
			@Override public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) {
				nextButton.setDisable(newValue.isEmpty());
			}
		});
		UploadData.instance.key1.bind(txtField1.textProperty());
		UploadData.instance.key2.bind(txtField2.textProperty());
		UploadData.instance.key3.bind(txtField3.textProperty());
		UploadData.instance.key4.bind(txtField4.textProperty());
		UploadData.instance.key5.bind(txtField5.textProperty());
		return VBoxBuilder.create().spacing(5).children(
				new Label("Add keywords to help in searching for your paper (pick at least 1)"),
				txtField1, txtField2, txtField3, txtField4, txtField5
				).build();
	}
}

/** This page gathers the title of the paper */
class AbstractPage extends WizardPage {
	public AbstractPage() {
		super("Abstract");
	}

	@Override
	Parent getContent() {
		TextArea textArea = TextAreaBuilder.create().wrapText(true).promptText("Tell me your abstract").build();
		nextButton.setDisable(true);
		finishButton.setDisable(true);
		textArea.textProperty().addListener(new ChangeListener<String>() {
			@Override public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) {
				nextButton.setDisable(newValue.isEmpty());
			}
		});
		UploadData.instance.abstrac.bind(textArea.textProperty());
		return VBoxBuilder.create().spacing(5).children(
				new Label("Please enter the abstract for your paper."),
				textArea
				).build();
	}
}

class ChooseFilePage extends WizardPage {
	public ChooseFilePage() {
		super("Choose file for upload");
	}
	
	void getFile() {
		FileChooser filechoose = FileChooserBuilder.create().build();
		File paper = filechoose.showOpenDialog(null);
		UploadData.instance.paper = paper;
	}
	@Override
	Parent getContent() {
		Button browse = new Button("Browse");
		browse.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent actionEvent) {
				getFile();
				finishButton.setDisable(false);
			}
		});
		nextButton.setDisable(true);
		finishButton.setDisable(true);
		
		return VBoxBuilder.create().spacing(5).children(
				new Label("Pick a file for upload"), browse).build();
		
	}
}

/** This page thanks the user for taking the survey */
class ThanksPage extends WizardPage {
	public ThanksPage() {
		super("Thanks");
	}

	@Override
	Parent getContent() {
		StackPane stack = StackPaneBuilder.create().children(
				new Label("Thanks!")
				).build();
		VBox.setVgrow(stack, Priority.ALWAYS);
		return stack;
	}
}